package com.food.restaurantpro.fragments;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Observable;
import java.util.Observer;

import com.food.restaurantpro.R;
import com.food.restaurantpro.RestaurantApp;
import com.food.restaurantpro.activity.MainActivity;
import com.food.restaurantpro.adapters.MenuPreOrderListViewAdapter;
import com.food.restaurantpro.connection.DataHelper;
import com.food.restaurantpro.connection.DataResult;
import com.food.restaurantpro.connection.IServerService.Methods;
import com.food.restaurantpro.connection.Urls;
import com.food.restaurantpro.database.tables.PlaceTable;
import com.food.restaurantpro.log.Log;
import com.food.restaurantpro.managingnetwork.ManagingNetwork;
import com.food.restaurantpro.objects.Food;
import com.food.restaurantpro.objects.Place;
import com.food.restaurantpro.objects.UserInfo;
import com.food.restaurantpro.observers.EditYourPreOrderObserver;
import com.food.restaurantpro.observers.EditYourPreOrderObserverInterface;
import com.food.restaurantpro.observers.PreOrderDetailObserver;
import com.food.restaurantpro.observers.PreOrderDetailObserverInterface;
import com.food.restaurantpro.observers.PreOrderObserver;
import com.food.restaurantpro.observers.PreOrderObserverInterface;
import com.food.restaurantpro.utils.AlertDialogInterface;
import com.food.restaurantpro.utils.AlertDialogManager;
import com.food.restaurantpro.utils.Prefs;
import com.food.restaurantpro.utils.Utils;

import android.app.AlertDialog;
import android.app.DatePickerDialog;
import android.app.Dialog;
import android.app.TimePickerDialog;
import android.app.DatePickerDialog.OnDateSetListener;
import android.app.TimePickerDialog.OnTimeSetListener;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.text.format.DateFormat;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.Toast;

public class MenuPreOrderFragment extends Fragment implements OnClickListener {

	private TextView tvHeader;
	private Button btnCancelPreOrder;
	private ListView mListView;
	private ArrayList<Food> mFoodList;
	private MenuPreOrderListViewAdapter mMenuPreOrderListViewAdapter;

	public TextView tvTotalPayment;
	private TextView tvOderPreOder;
	private Button btnPreOrder;
	private ArrayList<Place> mPlacelist;

	private RelativeLayout mRLFooterListViewPreOrder;
	private TextView mTvDate;
	private TextView mTvTime;
	private TextView mTvAddress;
	private Button mBtnDate;
	private Button mBtnTime;
	private Button mBtnAddress;
	//
	private String mCurrentDate;
	private String mCurrentTime;
	private int mYear;
	private int mMonth;
	private int mDay;
	private int mMinute;
	private int mHourOfDay;
	
	//
	private Prefs mPrefs;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		mPrefs = new Prefs(getActivity());
		
		View view = inflater.inflate(R.layout.fragment_menu_pre_order,
				container, false);
		tvHeader = (TextView) view.findViewById(R.id.tvHeader);
		tvHeader.setText(R.string.tvPreOrder_Title);

		btnCancelPreOrder = (Button) view.findViewById(R.id.btnCancelPreOrder);
		tvOderPreOder = (TextView) view.findViewById(R.id.tvOderPreOder);
		btnPreOrder = (Button) view.findViewById(R.id.btnPreOrder);

		btnCancelPreOrder.setOnClickListener(this);
		tvOderPreOder.setOnClickListener(this);
		btnPreOrder.setOnClickListener(this);
		tvTotalPayment = (TextView) view.findViewById(R.id.tvTotalCostPreOder);

		mListView = (ListView) view.findViewById(R.id.lvMenuPreOrder);
		// ---------------
		mRLFooterListViewPreOrder = (RelativeLayout) inflater.inflate(
				R.layout.footer_listview_pre_order, null, false);

		mTvDate = (TextView) mRLFooterListViewPreOrder
				.findViewById(R.id.tvDate);
		mTvTime = (TextView) mRLFooterListViewPreOrder
				.findViewById(R.id.tvTime);
		mTvAddress = (TextView) mRLFooterListViewPreOrder
				.findViewById(R.id.tvAddress);
		mBtnDate = (Button) mRLFooterListViewPreOrder
				.findViewById(R.id.btnDate);
		mBtnTime = (Button) mRLFooterListViewPreOrder
				.findViewById(R.id.btnTime);
		mBtnAddress = (Button) mRLFooterListViewPreOrder
				.findViewById(R.id.btnAddress);

		mTvTime.setOnClickListener(this);
		mBtnTime.setOnClickListener(this);
		
		mTvDate.setOnClickListener(this);
		mBtnDate.setOnClickListener(this);
		
		mTvAddress.setOnClickListener(this);
		mBtnAddress.setOnClickListener(this);

		mListView.addFooterView(mRLFooterListViewPreOrder);
		// --------------------------
		if(RestaurantApp.getInstance().isPreOrderObject()) {
			mFoodList = RestaurantApp.getInstance().getPreOrderObject().getOrderdetail();
			setDateTimeAddressFromEditYourPreOrder();
		} else {
			mFoodList = RestaurantApp.getInstance().getFoodList();
			setDateTimeAddressDefault();
		}
		
		if (mFoodList != null) {
			mMenuPreOrderListViewAdapter = new MenuPreOrderListViewAdapter(
					MenuPreOrderFragment.this, mFoodList, tvTotalPayment);
			mListView.setAdapter(mMenuPreOrderListViewAdapter);
		}

		return view;
	}
	private void setDateTimeAddressFromEditYourPreOrder() {
		Calendar cal = Calendar.getInstance();
		// int second = cal.get(Calendar.SECOND);
		mMinute = cal.get(Calendar.MINUTE);
		// 12 hour format
		// int hour = cal.get(Calendar.HOUR);
		// 24 hour format
		mHourOfDay = cal.get(Calendar.HOUR_OF_DAY);

		mCurrentTime = Integer.toString(mHourOfDay) + ":"
				+ Integer.toString(mMinute);

		mTvTime.setText(RestaurantApp.getInstance().getPreOrderObject().getPreorderTime());

		mYear = cal.get(Calendar.YEAR);
		mMonth = cal.get(Calendar.MONTH) + 1;
		mDay = cal.get(Calendar.DAY_OF_MONTH);

		mCurrentDate = "" + mMonth + "/" + mDay + "/" + mYear;
		mTvDate.setText(RestaurantApp.getInstance().getPreOrderObject().getPreorderDate());

		mPlacelist = PlaceTable.getAllPlaces();
		if (mPlacelist.size() > 0) {
			mTvAddress.setText(RestaurantApp.getInstance().getPreOrderObject().getPreorderPlaceAddress());
			String addressId = RestaurantApp.getInstance().getPreOrderObject().getPreorderPlaceID();
			for(int i = 0; i < mPlacelist.size(); i++) {
				if(addressId.equalsIgnoreCase(mPlacelist.get(i).getPlaceID())) {
					mTvAddress.setTag(new Integer(i));
					break;
				}
			}
		}
	}
	private void setDateTimeAddressDefault() {
		Calendar cal = Calendar.getInstance();
		// int second = cal.get(Calendar.SECOND);
		mMinute = cal.get(Calendar.MINUTE);
		// 12 hour format
		// int hour = cal.get(Calendar.HOUR);
		// 24 hour format
		mHourOfDay = cal.get(Calendar.HOUR_OF_DAY);

		mCurrentTime = Integer.toString(mHourOfDay) + ":"
				+ Integer.toString(mMinute);

		mTvTime.setText(mCurrentTime);

		mYear = cal.get(Calendar.YEAR);
		mMonth = cal.get(Calendar.MONTH) + 1;
		mDay = cal.get(Calendar.DAY_OF_MONTH);

		mCurrentDate = "" + mMonth + "/" + mDay + "/" + mYear;
		mTvDate.setText(mCurrentDate);

		mPlacelist = PlaceTable.getAllPlaces();
		if (mPlacelist.size() > 0) {
			mTvAddress.setText(mPlacelist.get(0).getPlaceAddress());
			mTvAddress.setTag(new Integer(0));
		}
	}

	private class DatePickerFragment extends DialogFragment implements
			OnDateSetListener {

		@Override
		public Dialog onCreateDialog(Bundle savedInstanceState) {
			/*// Use the current date as the default date in the picker
			final Calendar c = Calendar.getInstance();
			int year = c.get(Calendar.YEAR);
			int month = c.get(Calendar.MONTH);
			int day = c.get(Calendar.DAY_OF_MONTH);

			// Create a new instance of DatePickerDialog and return it
			return new DatePickerDialog(getActivity(), this, year, month, day);*/
			
			//Dung date duoc hien thi tren textview de set cho dialog
			return new DatePickerDialog(getActivity(), this, mYear, mMonth - 1, mDay);
		}

		@Override
		public void onDateSet(DatePicker view, int year, int month, int day) {
			// Do something with the date chosen by the user
			mYear = year;
			mMonth = month + 1;
			mDay = day;
			mTvDate.setText("" + mMonth + "/" + mDay + "/" + mYear);
			
			//SAVE lai ngay pre-order cuoi cung de khi qua man hinh reservation thi lay ra dung
			mPrefs.putIntValue(mYear, Prefs.KEY_LAST_YEAR_PRE_ORDER);
			mPrefs.putIntValue(mMonth, Prefs.KEY_LAST_MONTH_PRE_ORDER);
			mPrefs.putIntValue(mDay, Prefs.KEY_LAST_DAY_PRE_ORDER);
		}
	}

	private class TimePickerFragment extends DialogFragment implements
			OnTimeSetListener {

		@Override
		public Dialog onCreateDialog(Bundle savedInstanceState) {
			/*// Use the current time as the default values for the picker
			final Calendar c = Calendar.getInstance();
			int hour = c.get(Calendar.HOUR_OF_DAY);
			int minute = c.get(Calendar.MINUTE);

			// Create a new instance of TimePickerDialog and return it
			return new TimePickerDialog(getActivity(), this, hour, minute,
					DateFormat.is24HourFormat(getActivity()));*/
			
			//Dung time hien thi tren textview de set cho dialog
			return new TimePickerDialog(getActivity(), this, mHourOfDay, mMinute,
					DateFormat.is24HourFormat(getActivity()));
		}

		@Override
		public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
			// Do something with the time chosen by the user
			mTvTime.setText(Integer.toString(hourOfDay) + ":"
					+ Integer.toString(minute));
			MenuPreOrderFragment.this.mHourOfDay = hourOfDay;
			MenuPreOrderFragment.this.mMinute = minute;
			
			//SAVE lai gio-phut pre-order cuoi cung de khi qua man hinh reservation thi lay ra dung
			mPrefs.putIntValue(mHourOfDay, Prefs.KEY_LAST_HOUR_PRE_ORDER);
			mPrefs.putIntValue(mMinute, Prefs.KEY_LAST_MINUTE_PRE_ORDER);
		}
	}

	private void showDialogEditAddress() {
		int size = mPlacelist.size();
		if (size > 0) {
			final String[] items = new String[size];
			for (int i = 0; i < size; i++) {
				items[i] = "\n" + mPlacelist.get(i).getPlaceName() + "\n" + mPlacelist.get(i).getPlaceAddress() + "\n";
			}
			AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
			builder.setTitle(getActivity().getString(R.string.pick_a_place));
			builder.setIcon(R.drawable.address);
			builder.setSingleChoiceItems(items,
					((Integer) mTvAddress.getTag()).intValue(),
					new DialogInterface.OnClickListener() {

						@Override 
						public void onClick(DialogInterface dialog, int which) {
							// TODO Auto-generated method stub
							/*mTvAddress.setText(items[which]);*/
							mTvAddress.setText(mPlacelist.get(which).getPlaceAddress());
							mTvAddress.setTag(new Integer(which));
							dialog.dismiss();
						}
					});
			AlertDialog alert = builder.create();
			alert.setCanceledOnTouchOutside(true);
			alert.show();
		}
	}

	private void cancelOrder() {
		// TODO Auto-generated method stub
		((MainActivity) getActivity()).mBtnMenu.setSelected(false);
		((MainActivity) getActivity()).showMenuFragment();
	}

	private void preOrder() {
		if(RestaurantApp.getInstance().isPreOrderObject()) {
			editPreOrder();
		} else {
			addPreOrder();
		}
	}
	
	PreOrderObserver mPreOrderObserver;
	PreOrderDetailObserver mPreOrderDetailObserver;
	private void addPreOrder() {
		if(ManagingNetwork.isNetworkAvailable()) {
			if (mMenuPreOrderListViewAdapter != null
					&& mMenuPreOrderListViewAdapter.getTotalPayment() > 0) {
				if (!Utils.isEmpty(RestaurantApp.userInfo.getGenerateId())) {
					mPreOrderObserver = new PreOrderObserver(
							new PreOrderObserverInterface() {

								@Override
								public void preOrderCallback(String orderID,
										String messageError) {
									// TODO Auto-generated method stub
									if (messageError == null) {
										Log.i("MenuPreOrderFragment", "preOrderCallback", orderID);
										String url = Urls.LINK_TO_ADD_PRE_ORDER_DETAIL + "?res_order[order_id]=" + orderID;
										for (int i = 0; i < mFoodList.size(); i++) {
											url += "&"+"res_order[order_detail][" + (i+1) +"][1]=" + mFoodList.get(i).getFoodID()
													+"&"+ "res_order[order_detail][" + (i+1) +"][2]=" + mFoodList.get(i).getFoodAmount() ;
										}
										
										mPreOrderDetailObserver = new PreOrderDetailObserver(new PreOrderDetailObserverInterface() {
											
											@Override
											public void preOrderDetailCallback(String isSuccess, String messageError) {
												// TODO Auto-generated method stub
												Log.i("MenuPreOrderFragment", "preOrderDetailCallback", "isSuccess = " + isSuccess);
												if(messageError == null && "true".equalsIgnoreCase(isSuccess)) {
													showDialogReservation();
												} else {
													Toast.makeText(getActivity(), messageError, 1000).show();
												}
											}
										});
										mPreOrderDetailObserver.registerObserver(getActivity(), url);
									} else {
										Toast.makeText(getActivity(), "Add Pre-Order fail", 1000).show();
									}
								}
							});
					mPreOrderObserver.registerObserver(
							getActivity(),
							RestaurantApp.userInfo.getGenerateId(),
							mCurrentDate,
							mCurrentTime,
							mTvDate.getText().toString(),
							mTvTime.getText().toString(),
							mPlacelist.get(
									((Integer) mTvAddress.getTag()).intValue())
									.getPlaceID());
				} else {
					goToLogin();
				}
			} else {
				Toast.makeText(getActivity(), "Please choose a dish!", 1000).show();
			}
		} else {
			AlertDialogManager
			.showAlertDialog(getActivity(), new AlertDialogInterface() {

				@Override
				public void onChooseYesCallback() {
					// TODO Auto-generated method stub
				}

				@Override
				public void onChooseNoCallback() {
					// TODO Auto-generated method stub

				}
			}, false, true, RestaurantApp.CURRENT_CONTEXT
					.getString(R.string.title_internet_error),
					RestaurantApp.CURRENT_CONTEXT
					.getString(R.string.NETWORK_ERROR),
					RestaurantApp.CURRENT_CONTEXT
							.getString(R.string.ok), "", false);
		}
	}

	EditYourPreOrderObserver mEditYourPreOrderObserver;
	private void editPreOrder() {
		if(ManagingNetwork.isNetworkAvailable()) {
			if (mMenuPreOrderListViewAdapter != null
					&& mMenuPreOrderListViewAdapter.getTotalPayment() > 0) {
				if (!Utils.isEmpty(RestaurantApp.userInfo.getGenerateId())) {
					mEditYourPreOrderObserver = new EditYourPreOrderObserver(new EditYourPreOrderObserverInterface() {
						
						@Override
						public void editYourPreOrderCallback(String orderID, String messageError) {
							// TODO Auto-generated method stub
							if (messageError == null) {
								Log.i("MenuPreOrderFragment", "preOrderCallback", orderID);
								String url = Urls.LINK_TO_ADD_PRE_ORDER_DETAIL + "?res_order[order_id]=" + orderID;
								for (int i = 0; i < mFoodList.size(); i++) {
									url += "&"+"res_order[order_detail][" + (i+1) +"][1]=" + mFoodList.get(i).getFoodID()
											+"&"+ "res_order[order_detail][" + (i+1) +"][2]=" + mFoodList.get(i).getFoodAmount() ;
								}
								
								mPreOrderDetailObserver = new PreOrderDetailObserver(new PreOrderDetailObserverInterface() {
									
									@Override
									public void preOrderDetailCallback(String isSuccess, String messageError) {
										// TODO Auto-generated method stub
										Log.i("MenuPreOrderFragment", "preOrderDetailCallback", "isSuccess = " + isSuccess);
										if(messageError == null && "true".equalsIgnoreCase(isSuccess)) {
											showDialogReservation();
										} else {
											Toast.makeText(getActivity(), "Edit Pre-Order fail", 1000).show();
										}
									}
								});
								mPreOrderDetailObserver.registerObserver(getActivity(), url);
							} else {
								Toast.makeText(getActivity(), messageError, 1000).show();
							}
						}
					});
					mEditYourPreOrderObserver.registerObserver(getActivity(), RestaurantApp.getInstance().getPreOrderObject().getPreorderID(), mCurrentDate,
							mCurrentTime,
							mTvDate.getText().toString(),
							mTvTime.getText().toString(), mPlacelist.get(
							((Integer) mTvAddress.getTag()).intValue())
							.getPlaceID());	
				} else {
					goToLogin();
				}
			} else {
				Toast.makeText(getActivity(), "Please choose a dish!", 1000).show();
			}
		} else {
			AlertDialogManager
			.showAlertDialog(getActivity(), new AlertDialogInterface() {

				@Override
				public void onChooseYesCallback() {
					// TODO Auto-generated method stub
				}

				@Override
				public void onChooseNoCallback() {
					// TODO Auto-generated method stub

				}
			}, false, true, RestaurantApp.CURRENT_CONTEXT
					.getString(R.string.title_internet_error),
					RestaurantApp.CURRENT_CONTEXT
					.getString(R.string.NETWORK_ERROR),
					RestaurantApp.CURRENT_CONTEXT
							.getString(R.string.ok), "", false);
		}
	}
	
	private void showDialogReservation() {
		AlertDialogManager.showCustomDialog(getActivity(), new AlertDialogInterface() {
			
			@Override
			public void onChooseYesCallback() {
				// TODO Auto-generated method stub
				((MainActivity)getActivity()).showReservationFragment();
			}
			
			@Override
			public void onChooseNoCallback() {
				// TODO Auto-generated method stub
				if(RestaurantApp.getInstance().isPreOrderObject()) {
					getActivity().onBackPressed();
				} else {
					((MainActivity)getActivity()).showYourPreOrderFragment();
				}
			}
		}, "Reservation", "You make pre-order successfully. Do you want to make a seat reservation for this pre-order?", "Yes", "No", false);
	}
	// method is called in MenuPreOrderListViewAdapter
	public void removeItemOfListView(int index) {
		mListView.setAdapter(null);
		mMenuPreOrderListViewAdapter = null;
		mFoodList.remove(index);
		if (mFoodList.size() > 0) {
			mMenuPreOrderListViewAdapter = new MenuPreOrderListViewAdapter(
					MenuPreOrderFragment.this, mFoodList, tvTotalPayment);
			mListView.setAdapter(mMenuPreOrderListViewAdapter);
		} else {
			getActivity().onBackPressed();
		}
	}

	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		switch (v.getId()) {
		case R.id.btnCancelPreOrder:
			cancelOrder();
			break;
		case R.id.btnPreOrder:
		case R.id.tvOderPreOder:
			preOrder();
			break;
		case R.id.btnDate:
		case R.id.tvDate:
			DialogFragment newDateFragment = new DatePickerFragment();
			newDateFragment.show(getActivity().getSupportFragmentManager(),
					"datePicker");
			break;
		case R.id.btnTime:
		case R.id.tvTime:
			DialogFragment newTimeFragment = new TimePickerFragment();
			newTimeFragment.show(getActivity().getSupportFragmentManager(),
					"timePicker");
			break;
		case R.id.btnAddress:
		case R.id.tvAddress:
			showDialogEditAddress();
			break;
		default:
			break;
		}
	}

	@Override
	public void onDestroy() {
		// TODO delete image and cache de giai phong bo nho
		super.onDestroy();
		//
		mListView.setAdapter(null);
		if (mMenuPreOrderListViewAdapter != null) {
			mMenuPreOrderListViewAdapter.clearMemoryCache();
			mMenuPreOrderListViewAdapter = null;
		}
		//
		if (mFoodList != null) {
			mFoodList.clear();
			mFoodList = null;
		}
		if(mPreOrderObserver != null) {
			mPreOrderObserver.unRegisterObserver();
			mPreOrderObserver = null;
		}
		if(mEditYourPreOrderObserver != null) {
			mEditYourPreOrderObserver.unRegisterObserver();
			mEditYourPreOrderObserver = null;
		}
		if(mPreOrderDetailObserver != null) {
			mPreOrderDetailObserver.unRegisterObserver();
			mPreOrderDetailObserver = null;
		}
		
		Runtime.getRuntime().gc();
	}
	
	AlertDialog dialog;
	private void goToLogin() {
		LayoutInflater inflater = getActivity().getLayoutInflater();
		View dialoglayout = inflater.inflate(R.layout.custom_dialog_login, null);
		AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
		builder.setView(dialoglayout);
		Button btnCancel = (Button) dialoglayout.findViewById(R.id.btnDialogLoginCancel);
		Button btnYes = (Button) dialoglayout.findViewById(R.id.btnDialogLoginYes);
		Button btnClose = (Button) dialoglayout.findViewById(R.id.btnDialogLoginExit);
		//TextView tvTitle = (TextView) dialoglayout.findViewById(R.id.tvDialogLoginTitle);
		//TextView tvContent = (TextView) dialoglayout.findViewById(R.id.tvDialogLoginContent);
		final EditText edtCode = (EditText) dialoglayout.findViewById(R.id.edtLoginNumber);
		btnCancel.setText("No");
		btnYes.setText("Yes");
		btnClose.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				dialog.cancel();
			}
		});
		btnCancel.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				dialog.cancel();
			}
		});
		btnYes.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				 dialog.cancel();
				 if (edtCode.getText().toString().length() > 0) {
					 DataHelper.getInstance().addObserver(new Observer() {
						@Override
						public void update(Observable observable, Object data) {
							// TODO Auto-generated method stub
							DataResult result = (DataResult) data;
							if (result.getMethodName().equals(Methods.login)) {
								UserInfo userInfo = (UserInfo) result.getData();
								if(userInfo != null && !Utils.isEmpty(userInfo.getUserId())) {
									UserInfo.saveCurrentUserInfo(userInfo);
									RestaurantApp.userInfo = userInfo;
									Utils.showToast("Login succesfull");
									preOrder();
								} else {
									Utils.showToast("Login fail");
								}
								DataHelper.getInstance().deleteObserver(this);
							}
						}
					});
					 DataHelper.getInstance().login(edtCode.getText().toString());
				}else {
					Toast.makeText(getActivity(), "Please enter your code the restaurant provide for you.", Toast.LENGTH_SHORT).show();
				}
			}
		});
		dialog = builder.create();
		dialog.setCanceledOnTouchOutside(false);
		dialog.show();
	}
}
